package org.ktx.osr.service

import android.content.Context
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.media.MediaRecorder
import android.media.projection.MediaProjection
import android.os.Build
import android.util.Log
import org.ktx.osr.audio.SystemAudioRecorder
import org.ktx.osr.ui.AppSettings
import java.io.File

/**
 * 录制会话管理类
 * 负责管理单次录制的所有资源和状态
 * 功能边界：仅管理录制会话的生命周期，不处理UI和通知
 */
class RecordingSession(
    private val context: Context,
    private val settings: AppSettings,
    private val mediaProjection: MediaProjection
) {
    private var mediaRecorder: MediaRecorder? = null
    private var virtualDisplay: VirtualDisplay? = null
    private var systemAudioRecorder: SystemAudioRecorder? = null
    private var tempVideoFile: File? = null
    private var tempAudioFile: File? = null
    private var isActive = false

    companion object {
        private const val TAG = "RecordingSession"
    }

    /**
     * 开始录制会话
     */
    fun startSession(): Boolean {
        if (isActive) {
            Log.w(TAG, "Session already active")
            return false
        }

        return try {
            // 创建临时文件
            tempVideoFile = createTempVideoFile()
            tempAudioFile = createTempAudioFile()
            
            if (tempVideoFile == null) {
                Log.e(TAG, "Failed to create temp video file")
                return false
            }

            // 设置视频录制器
            if (!setupVideoRecorder()) {
                Log.e(TAG, "Failed to setup video recorder")
                return false
            }

            // 创建虚拟显示
            if (!createVirtualDisplay()) {
                Log.e(TAG, "Failed to create virtual display")
                return false
            }

            // 开始视频录制
            mediaRecorder?.start()

            // 开始音频录制（如果需要）
            if (settings.includeSystemSound || settings.includeMicrophone) {
                startAudioRecording()
            }

            isActive = true
            Log.d(TAG, "Recording session started successfully")
            true

        } catch (e: Exception) {
            Log.e(TAG, "Failed to start recording session", e)
            stopSession()
            false
        }
    }

    /**
     * 停止录制会话
     */
    fun stopSession() {
        if (!isActive) return

        try {
            // 停止音频录制
            systemAudioRecorder?.stopRecording()

            // 停止视频录制
            mediaRecorder?.apply {
                stop()
                reset()
            }
        } catch (e: Exception) {
            Log.e(TAG, "Error stopping recording session", e)
        } finally {
            // 释放所有资源
            releaseResources()
            isActive = false
            Log.d(TAG, "Recording session stopped")
        }
    }

    /**
     * 暂停录制
     */
    fun pauseRecording() {
        if (!isActive) return
        try {
            mediaRecorder?.pause()
        } catch (e: Exception) {
            Log.e(TAG, "Error pausing recording", e)
        }
    }

    /**
     * 恢复录制
     */
    fun resumeRecording() {
        if (!isActive) return
        try {
            mediaRecorder?.resume()
        } catch (e: Exception) {
            Log.e(TAG, "Error resuming recording", e)
        }
    }

    /**
     * 获取视频文件
     */
    fun getVideoFile(): File? = tempVideoFile

    /**
     * 获取音频文件
     */
    fun getAudioFile(): File? = tempAudioFile

    /**
     * 检查会话是否活跃
     */
    fun isActive(): Boolean = isActive

    /**
     * 设置视频录制器
     */
    private fun setupVideoRecorder(): Boolean {
        return try {
            mediaRecorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                MediaRecorder(context)
            } else {
                @Suppress("DEPRECATION")
                MediaRecorder()
            }

            val videoPath = tempVideoFile?.absolutePath
            if (videoPath == null) {
                mediaRecorder = null
                return false
            }

            // 配置MediaRecorder（仅视频）
            val (width, height) = org.ktx.osr.util.SettingsUtils.parseResolution(
                settings.resolution,
                1920, 1080
            )
            val frameRate = org.ktx.osr.util.SettingsUtils.parseFrameRate(settings.frameRate)
            val outputFormat = org.ktx.osr.util.SettingsUtils.parseVideoFormat(settings.videoFormat)
            val bitrate = org.ktx.osr.util.SettingsUtils.getVideoBitrate(settings.resolution, frameRate)

            mediaRecorder?.apply {
                setVideoSource(MediaRecorder.VideoSource.SURFACE)
                setOutputFormat(outputFormat)
                setOutputFile(videoPath)
                setVideoSize(width, height)
                setVideoEncoder(MediaRecorder.VideoEncoder.H264)
                setVideoEncodingBitRate(bitrate)
                setVideoFrameRate(frameRate)
                setOnErrorListener { _, what, extra ->
                    Log.e(TAG, "MediaRecorder error: $what, $extra")
                    stopSession()
                }
            }

            mediaRecorder?.prepare()
            true
        } catch (e: Exception) {
            Log.e(TAG, "Failed to setup video recorder", e)
            mediaRecorder = null
            false
        }
    }

    /**
     * 创建虚拟显示
     */
    private fun createVirtualDisplay(): Boolean {
        return try {
            val metrics = context.resources.displayMetrics
            val screenDensity = metrics.densityDpi
            val (width, height) = org.ktx.osr.util.SettingsUtils.parseResolution(
                settings.resolution,
                1920, 1080
            )

            virtualDisplay = mediaProjection.createVirtualDisplay(
                "ScreenRecording",
                width, height, screenDensity,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mediaRecorder?.surface, null, null
            )

            virtualDisplay != null
        } catch (e: Exception) {
            Log.e(TAG, "Failed to create virtual display", e)
            false
        }
    }

    /**
     * 开始音频录制
     */
    private fun startAudioRecording() {
        try {
            val audioFile = tempAudioFile
            if (audioFile != null) {
                systemAudioRecorder = SystemAudioRecorder(context, settings, mediaProjection)
                val audioStarted = systemAudioRecorder?.startRecording(audioFile) ?: false
                if (!audioStarted) {
                    Log.w(TAG, "Failed to start audio recording")
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "Error starting audio recording", e)
        }
    }

    /**
     * 创建临时视频文件
     */
    private fun createTempVideoFile(): File? {
        return try {
            val directory = getRecordingDirectory()
            if (!directory.exists()) {
                directory.mkdirs()
            }
            val timestamp = java.text.SimpleDateFormat("yyyyMMdd_HHmmss", java.util.Locale.getDefault())
                .format(java.util.Date())
            File(directory, "video_$timestamp.mp4")
        } catch (e: Exception) {
            Log.e(TAG, "Failed to create temp video file", e)
            null
        }
    }

    /**
     * 创建临时音频文件
     */
    private fun createTempAudioFile(): File? {
        return try {
            val directory = getRecordingDirectory()
            if (!directory.exists()) {
                directory.mkdirs()
            }
            val timestamp = java.text.SimpleDateFormat("yyyyMMdd_HHmmss", java.util.Locale.getDefault())
                .format(java.util.Date())
            File(directory, "audio_$timestamp.aac")
        } catch (e: Exception) {
            Log.e(TAG, "Failed to create temp audio file", e)
            null
        }
    }

    /**
     * 获取录制目录
     */
    private fun getRecordingDirectory(): File {
        return when (settings.saveLocation) {
            "SD Card" -> {
                try {
                    val publicDir = File(
                        android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_MOVIES),
                        "ScreenRecordings"
                    )
                    if (publicDir.exists() || publicDir.mkdirs()) {
                        val testFile = File(publicDir, "test_write.tmp")
                        if (testFile.createNewFile()) {
                            testFile.delete()
                            return publicDir
                        }
                    }
                } catch (e: Exception) {
                    Log.w(TAG, "Cannot write to public directory, using app-specific directory", e)
                }
                File(context.getExternalFilesDir(android.os.Environment.DIRECTORY_MOVIES), "ScreenRecordings")
            }
            else -> {
                File(context.getExternalFilesDir(android.os.Environment.DIRECTORY_MOVIES), "ScreenRecordings")
            }
        }
    }

    /**
     * 释放所有资源
     */
    private fun releaseResources() {
        try {
            mediaRecorder?.release()
            virtualDisplay?.release()
            systemAudioRecorder = null
        } catch (e: Exception) {
            Log.e(TAG, "Error releasing resources", e)
        } finally {
            mediaRecorder = null
            virtualDisplay = null
            systemAudioRecorder = null
        }
    }
}
